﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.ComponentModel;

using Nui.Vision;
using xn;

namespace LizaBeta
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        NuiUserTracker _skeleton;
        BackgroundWorker _worker = new BackgroundWorker();
        Color[] _userColors = { Colors.Blue, Colors.Red, Colors.Green, Colors.Yellow, Colors.Pink, Colors.Black };

        LinkObject[] m_LinkOBArray = new LinkObject[9];
        ImageBrush[] m_BrushSets = new ImageBrush[9];

        string m_checkPatten;
        float m_Skeleton_OffSet_X;
        float m_Skeleton_OffSet_Y;

        float m_Grid_X1 = 200;
        float m_Grid_X2 = 400;
        float m_Grid_Z1 = 1500;
        float m_Grid_Z2 = 2500;
        string m_bi_address = "";

        public MainWindow()
        {
            InitializeComponent();

            m_BrushSets[0] = brushA1;
            m_BrushSets[1] = brushA2;
            m_BrushSets[2] = brushA3;
            m_BrushSets[3] = brushB1;
            m_BrushSets[4] = brushB2;
            m_BrushSets[5] = brushB3;
            m_BrushSets[6] = brushC1;
            m_BrushSets[7] = brushC2;
            m_BrushSets[8] = brushC3;

            m_Skeleton_OffSet_X = (float)this.Width / 2;
            m_Skeleton_OffSet_Y = (float)this.Height / 2;

            m_Skeleton_OffSet_X = 0;
            m_Skeleton_OffSet_Y = 0;

            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
            _skeleton = new NuiUserTracker(@"SamplesConfig.xml");
            _skeleton.UserUpdated += new NuiUserTracker.UserUpdatedHandler(Skeleton_UserUpdated);

            _worker.DoWork += new DoWorkEventHandler(Worker_DoWork);


        }

        void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Dispatcher.BeginInvoke((Action)delegate
            {
                imgCamera.Source = _skeleton.RawImage;
            });
        }

        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            if (!_worker.IsBusy)
            {
                _worker.RunWorkerAsync();
            }
        }

        void Skeleton_UserUpdated(object sender, NuiUserEventArgs e)
        {
            Dispatcher.BeginInvoke((Action)delegate
            {
                LayoutRoot.Children.Clear();
                foreach (var user in e.Users)
                {
                    Color userColor = _userColors[user.Id - 1];

                    #region Get body parts coordinates

                    float headX = user.Head.X + m_Skeleton_OffSet_X;
                    float headY = user.Head.Y + m_Skeleton_OffSet_Y;

                   // Console.WriteLine("Head Location X= {0}, Y = {1} , Z = {2}", user.Head.X, user.Head.Y, user.Head.Z);
                   ChangeBackGround(headX, headY, user.Head.Z);

                    float neckX = user.Neck.X + m_Skeleton_OffSet_X;
                    float neckY = user.Neck.Y + m_Skeleton_OffSet_Y;


                    float leftShoulderX = user.LeftShoulder.X + m_Skeleton_OffSet_X;
                    float leftShoulderY = user.LeftShoulder.Y + m_Skeleton_OffSet_Y;

                    float leftElbowX = user.LeftElbow.X + m_Skeleton_OffSet_X ;
                    float leftElbowY = user.LeftElbow.Y + m_Skeleton_OffSet_Y;

                    float leftHandX = user.LeftHand.X + m_Skeleton_OffSet_X;
                    float leftHandY = user.LeftHand.Y + m_Skeleton_OffSet_Y;

                    float rightSholuderX = user.RightShoulder.X + m_Skeleton_OffSet_X;
                    float rightShoulderY = user.RightShoulder.Y + m_Skeleton_OffSet_Y;

                    float rightElbowX = user.RightElbow.X + m_Skeleton_OffSet_X;
                    float rightElbowY = user.RightElbow.Y + m_Skeleton_OffSet_Y;

                    float rightHandX = user.RightHand.X + m_Skeleton_OffSet_X;
                    float rightHandY = user.RightHand.Y + m_Skeleton_OffSet_Y;

                    float waistX = user.Torso.X + m_Skeleton_OffSet_X;
                    float waistY = user.Torso.Y + m_Skeleton_OffSet_Y;

                    float leftHipX = user.LeftHip.X + m_Skeleton_OffSet_X;
                    float leftHipY = user.LeftHip.Y + m_Skeleton_OffSet_Y;

                    float leftKneeX = user.LeftKnee.X + m_Skeleton_OffSet_X;
                    float leftKneeY = user.LeftKnee.Y + m_Skeleton_OffSet_Y;

                    float leftFootX = user.LeftFoot.X + m_Skeleton_OffSet_X;
                    float leftFootY = user.LeftFoot.Y + m_Skeleton_OffSet_Y;

                    float rightHipX = user.RightHip.X + m_Skeleton_OffSet_X;
                    float rightHipY = user.RightHip.Y + m_Skeleton_OffSet_Y;

                    float rightKneeX = user.RightKnee.X + m_Skeleton_OffSet_X;
                    float rightKneeY = user.RightKnee.Y + m_Skeleton_OffSet_Y;

                    float rightFootX = user.RightFoot.X + m_Skeleton_OffSet_X;
                    float rightFootY = user.RightFoot.Y + m_Skeleton_OffSet_Y;

                    #endregion

                    #region Draw skeleton points

                    DrawCircle(headX, headY, userColor);
                    DrawCircle(neckX, neckY, userColor);
                    DrawCircle(leftShoulderX, leftShoulderY, userColor);
                    DrawCircle(leftElbowX, leftElbowY, userColor);
                    DrawCircle(leftHandX, leftHandY, userColor);
                    DrawCircle(waistX, waistY, userColor);
                    DrawCircle(rightSholuderX, rightShoulderY, userColor);
                    DrawCircle(rightElbowX, rightElbowY, userColor);
                    DrawCircle(rightHandX, rightHandY, userColor);
                    DrawCircle(leftHipX, leftHipY, userColor);
                    DrawCircle(leftKneeX, leftKneeY, userColor);
                    DrawCircle(leftFootX, leftFootY, userColor);
                    DrawCircle(rightHipX, rightHipY, userColor);
                    DrawCircle(rightKneeX, rightKneeY, userColor);
                    DrawCircle(rightFootX, rightFootY, userColor);

                    #endregion
                }
            });
        }

        private void ChangeBackGround(float headX, float headY, float headZ)
        {
            if (headZ < m_Grid_Z1)
            {
                if (headX < m_Grid_X1)
                {
                    //change to A1
                    if (m_bi_address != m_LinkOBArray[0].MediaPath)
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.BeginInit();
                        bi.UriSource = new Uri(m_LinkOBArray[0].MediaPath);
                        bi.EndInit();
                        m_bi_address = m_LinkOBArray[0].MediaPath;
                        imgBG.Source = bi;
                    }
                }
                else if (headX > m_Grid_X1 && headX < m_Grid_X2)
                {
                    //change to A2
                    if (m_bi_address != m_LinkOBArray[1].MediaPath)
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.BeginInit();
                        bi.UriSource = new Uri(m_LinkOBArray[1].MediaPath);
                        bi.EndInit();
                        m_bi_address = m_LinkOBArray[1].MediaPath;
                        imgBG.Source = bi;
                    }
                }
                else if (headX > m_Grid_X2)
                {
                    //chnage to A3

                    if (m_bi_address != m_LinkOBArray[2].MediaPath)
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.BeginInit();
                        bi.UriSource = new Uri(m_LinkOBArray[2].MediaPath);
                        bi.EndInit();
                        m_bi_address = m_LinkOBArray[2].MediaPath;
                        imgBG.Source = bi;
                    }
                }
            }
            else if (headZ > m_Grid_Z1 && headZ < m_Grid_Z2)
            {
                if (headX < m_Grid_X1)
                {
                    //change to B1
                    if (m_bi_address != m_LinkOBArray[3].MediaPath)
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.BeginInit();
                        bi.UriSource = new Uri(m_LinkOBArray[3].MediaPath);
                        bi.EndInit();
                        m_bi_address = m_LinkOBArray[3].MediaPath;
                        imgBG.Source = bi;
                    }
                }
                else if (headX > m_Grid_X1 && headX < m_Grid_X2)
                {
                    //change to B2
                    if (m_bi_address != m_LinkOBArray[4].MediaPath)
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.BeginInit();
                        bi.UriSource = new Uri(m_LinkOBArray[4].MediaPath);
                        bi.EndInit();
                        m_bi_address = m_LinkOBArray[4].MediaPath;
                        imgBG.Source = bi;
                    }
                }
                else if (headX > m_Grid_X2)
                {
                    //chnage to B3
                    if (m_bi_address != m_LinkOBArray[5].MediaPath)
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.BeginInit();
                        bi.UriSource = new Uri(m_LinkOBArray[5].MediaPath);
                        bi.EndInit();
                        m_bi_address = m_LinkOBArray[5].MediaPath;
                        imgBG.Source = bi;
                    }
                }
            }
            else if (headZ > m_Grid_Z2)
            {
                if (headX < m_Grid_X1)
                {
                    //change to C1
                    if (m_bi_address != m_LinkOBArray[6].MediaPath)
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.BeginInit();
                        bi.UriSource = new Uri(m_LinkOBArray[6].MediaPath);
                        bi.EndInit();
                        m_bi_address = m_LinkOBArray[6].MediaPath;
                        imgBG.Source = bi;
                    }
                }
                else if (headX > m_Grid_X1 && headX < m_Grid_X2)
                {
                    //change to C2
                    if (m_bi_address != m_LinkOBArray[7].MediaPath)
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.BeginInit();
                        bi.UriSource = new Uri(m_LinkOBArray[7].MediaPath);
                        bi.EndInit();
                        m_bi_address = m_LinkOBArray[7].MediaPath;
                        imgBG.Source = bi;
                    }
                }
                else if (headX > m_Grid_X2)
                {
                    //chnage to C3
                    if (m_bi_address != m_LinkOBArray[8].MediaPath)
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.BeginInit();
                        bi.UriSource = new Uri(m_LinkOBArray[8].MediaPath);
                        bi.EndInit();
                        m_bi_address = m_LinkOBArray[8].MediaPath;
                        imgBG.Source = bi;
                    }
                }
            }
        }

        void DrawCircle(float positionX, float positionY, Color color)
        {
            Ellipse ellipse = new Ellipse
            {
                Fill = new SolidColorBrush(color),
                Width = 30,
                Height = 30,
                Margin = new Thickness(positionX, positionY, 0, 0)
            };

            LayoutRoot.Children.Add(ellipse);
        }

        private void Bt_BrowseImage_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog imageDialog = new OpenFileDialog();
            imageDialog.Filter = "Image Files (*.bmp, *.jpg, *.jpeg, *.png)|*.bmp;*.jpg;*.jpeg; *.png";

            Nullable<bool> result = imageDialog.ShowDialog();

            if (result == true)
            {
                TBox_Image.Text = imageDialog.FileName;
            }
        }

        private void Bt_Assign_Click(object sender, RoutedEventArgs e)
        {
            m_checkPatten = "";

            CheckAllBoxes(GD_Upload);
            if (m_checkPatten != "")
            {
                LinkObject lOB = new LinkObject();
                for (int i = 0; i < m_checkPatten.Length; i++)
                {
                    lOB.MediaPath = TBox_Image.Text;
                    lOB.AudioPath = TBox_Audio.Text;
                    int index = Convert.ToInt32(m_checkPatten[i].ToString());
                    m_LinkOBArray[index -1] = lOB;

                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.UriSource = new Uri(lOB.MediaPath);
                    bi.EndInit();

                    m_BrushSets[index - 1].ImageSource = bi;
                }
            }

        }

        public void CheckAllBoxes(DependencyObject obj)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                // If a checkbox, change IsChecked and continue.
                if (obj is CheckBox)
                {
                    if (((CheckBox)obj).IsChecked == true)
                    {
                        m_checkPatten += ((CheckBox)obj).Tag.ToString();
                        ((CheckBox)obj).IsChecked = false;
                    }
                    continue;
                }

                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                CheckAllBoxes(child);
            }
        }

        private void Bt_BrowseAudio_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog audioDialog = new OpenFileDialog();
            audioDialog.Filter = "Audio Files (*.mp3, *.wav)|*.mp3;*.wav";

            Nullable<bool> result = audioDialog.ShowDialog();

            if (result == true)
            {
                TBox_Audio.Text = audioDialog.FileName;
            }
        }

        private void Bt_Run_Click(object sender, RoutedEventArgs e)
        {
            ImageGrid.Visibility = System.Windows.Visibility.Hidden;
            GD_Upload.Visibility = System.Windows.Visibility.Hidden;
            LiveImage.Visibility = System.Windows.Visibility.Visible;
        }

        private void Window_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                ImageGrid.Visibility = System.Windows.Visibility.Visible;
                GD_Upload.Visibility = System.Windows.Visibility.Visible;
                LiveImage.Visibility = System.Windows.Visibility.Hidden;
            }
        }

    }
}
